Skip to content

feat: Experiemtal annotated argparse#1666

Open
KelvinChung2000 wants to merge 11 commits into
mainfrom
feat/annotated-argparse
Open

feat: Experiemtal annotated argparse#1666
KelvinChung2000 wants to merge 11 commits into
mainfrom
feat/annotated-argparse

Conversation

@KelvinChung2000
Copy link
Copy Markdown

Adds @with_annotated, a type-hint-driven alternative to @with_argparser that builds the parser automatically from a command's signature (positional/option inference, enum/literal/path/collection handling, subcommands, groups, mutex). Marked experimental.

  • New module cmd2/annotated.py plus Argument / Option metadata classes exported from cmd2
  • Underscored param names auto-dasherize in generated flags (dry_run--dry-run); opt out via Option("--my_flag")
  • Dedicated docs page docs/features/annotated.md with an experimental admonition; argument_processing.md keeps a short pointer
  • Example app examples/annotated_example.py and test suite in tests/test_annotated.py

Adds @with_annotated decorator that builds argparse parsers from type-annotated
function signatures. Supports Annotated[T, Argument(...)] / Annotated[T, Option(...)]
metadata, automatic positional/option detection, optional unwrapping, collections,
enums, literals, Path completion, subcommands via subcommand_to=, base_command=True
with cmd2_handler dispatch, and argument/mutually-exclusive groups.

- New module cmd2/annotated.py with Argument, Option, with_annotated, and
  build_parser_from_function helpers
- Comprehensive test suite in tests/test_annotated.py
- Example in examples/annotated_example.py
- Docs updates in docs/features/argument_processing.md
@codecov
Copy link
Copy Markdown

codecov Bot commented May 15, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.58%. Comparing base (eded33c) to head (b6a9832).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1666      +/-   ##
==========================================
+ Coverage   99.55%   99.58%   +0.03%     
==========================================
  Files          22       23       +1     
  Lines        4920     5362     +442     
==========================================
+ Hits         4898     5340     +442     
  Misses         22       22              
Flag Coverage Δ
unittests 99.58% <100.00%> (+0.03%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@tleonhardt
Copy link
Copy Markdown
Member

I plan to review this PR this weekend. @kmvanbrunt @bambu I'd very much appreciate your feedback as well.

@tleonhardt tleonhardt added this to the 4.0.0 milestone May 15, 2026
Comment thread cmd2/annotated.py Outdated
Comment thread cmd2/annotated.py Outdated
Comment thread cmd2/annotated.py Outdated
Comment thread examples/annotated_example.py
Comment thread cmd2/annotated.py Outdated
@kmvanbrunt
Copy link
Copy Markdown
Member

@KelvinChung2000

How can I do the following?

  1. Set the title and description for an argument group?
  2. Set the description and epilog for a parser?
  3. Set a custom help formatter class for a parser?
  4. Use a custom parser class?

Comment thread cmd2/__init__.py Outdated
KelvinChung2000 and others added 6 commits May 19, 2026 15:14
- aliases param: Sequence[str] = () to match as_subcommand_to()
- update aliases None checks now that it defaults to ()
- type with_annotated via @overload (no longer untyped decorator)
- drop experimental annotated exports from cmd2/__init__.py
- import from cmd2.annotated in example/tests/docs; fix example mypy
- Group(*members, title=, description=) for titled argument-group
sections
  (groups= now accepts bare tuples or Group)
- description= and epilog= for the generated parser
- formatter_class= for a custom help formatter
- parser_class= for a custom parser class

Includes tests, example command, and docs.
Adds VerbatimHelpFormatter and StrictArgumentParser subclasses and a
do_report command so all four parser-customization features have a
runnable demonstration, not just docs/tests.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drop bare tuple[str, ...] support; entries must be Group instances.
Removes the _group_members shim and adds an explicit TypeError guard
(_require_group) so a wrong type fails clearly instead of with an
AttributeError. Updates tests and docs accordingly.
Adds a do_export command so mutually_exclusive_groups has a runnable
demo alongside the existing groups demo.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants